
package com.kit;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;

/**
 * @author 石头哥哥
 *         </P>
 *         Date:   2015/7/23
 *         </P>
 *         Time:   15:24
 *         </P>
 *         Package: mengchongdoc
 *         </P>
 *         <p/>
 *         注解： 基于jackson mapper获取
 *         <p/>
 *         ObjectMapperFactory  默认是单例
 */
@Component
public class ObjectMapperFactory {

    /**
     * 记录序列化失败异常
     */
    private static final Logger LOGGER = LoggerFactory.getLogger("debugLogger");

    /**
     * json object mapper
     * thread safe !
     */
    private static final ObjectMapper mapper = new ObjectMapper();

    /**
     * 初始化mapper 以支持json中中文字符转化为unicode
     */
    @PostConstruct
    private void initMapper() {
        mapper.getFactory().configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }

    /**
     * @param fromValue
     * @param toValueType
     * @param <T>
     * @return
     */
    public <T> T readValue(String fromValue, Class<T> toValueType) {
        try {
            return mapper.readValue(fromValue, toValueType);
        } catch (IOException e) {
            LOGGER.debug("object:" + fromValue + " 序列化json失败->" + e.getMessage());
            return null;
        }
    }


    /***
     *
     * @param fromValue
     * @param collectionClass
     * @param elementClass
     * @param <T>
     * @return
     */
    public <T> T readValue(String fromValue, Class<? extends Collection> collectionClass, Class<?> elementClass) {
        try {
            return mapper.readValue(fromValue, mapper.getTypeFactory().constructCollectionType(collectionClass, elementClass));
        } catch (IOException e) {
            LOGGER.debug("object:" + fromValue + " 序列化json失败->" + e.getMessage());
            return null;
        }
    }


    /***
     *
     * @param fromValue
     * @param collectionClass
     * @param elementClass
     * @param <T>
     * @return
     */
    public <T> T readValue(byte[] fromValue, Class<? extends Collection> collectionClass, Class<?> elementClass) {
        try {
            return mapper.readValue(fromValue, mapper.getTypeFactory().constructCollectionType(collectionClass, elementClass));
        } catch (IOException e) {
            LOGGER.debug("object:" + new String(fromValue) + " 序列化json失败->" + e.getMessage());
            return null;
        }
    }


    /**
     * @param url
     * @param toValueType
     * @param <T>
     * @return
     */
    public <T> T readValue(URL url, Class<T> toValueType) {
        try {
            return mapper.readValue(url, toValueType);
        } catch (IOException e) {
            LOGGER.debug("object:" + url + " 序列化json失败->" + e.getMessage());
            return null;
        }
    }


    /**
     * 转化json字符串
     *
     * @param objectVo 数据构建对象
     * @return
     */
    public String writeValueAsString(Object objectVo) {
        try {
            return mapper.writeValueAsString(objectVo);
        } catch (JsonProcessingException e) {
            LOGGER.debug("object:" + objectVo + " 序列化json失败->" + e.getMessage());
            return null;
        }
    }


}
